package com.lin.server.thread;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 *
 * @author ruoyi
 **/
@Configuration
public class ThreadPoolConfig implements InitializingBean {
    // 核心线程池大小 corePoolSize = CPU核数 * 2
    private int corePoolSize;

    // 最大可创建的线程数
    private int maxPoolSize;

    // 队列最大长度
    private int queueCapacity;

    // 线程池维护线程所允许的空闲时间
    private int keepAliveSeconds;

    @Override
    public void afterPropertiesSet() throws Exception {
        int cpuCores = Runtime.getRuntime().availableProcessors();
        this.corePoolSize = cpuCores * 2;
        this.maxPoolSize = this.corePoolSize;
        this.queueCapacity = 10;
        this.keepAliveSeconds = 10;
    }

    /**
     * 线程池
     *
     * @return
     */
    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        executor.setCorePoolSize(corePoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    /**
     * 线程池：执行周期性或定时任务
     */
    @Bean(name = "scheduledThreadPoolExecutor")
    public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor() {
        return new ScheduledThreadPoolExecutor(
                this.corePoolSize,
                new CusThreadFactory(true),
                new ThreadPoolExecutor.CallerRunsPolicy()); // 线程池饱和策略：当线程池满了并且无法处理新任务时，它会让调用线程（提交任务的线程）来执行这个任务。
    }
}
